package keeto.com.vn.classified.utils;

import java.util.HashMap;

/**
 * @author 陆扬 washpan
 * @category 管理缓存的工具类 {@link http://sishuok.com/forum/blogPost/list/342.html}
 * */
public class SabonaCache {
	
	public SabonaCache(int cacheSize){
		this.cacheSize = cacheSize;
	}
	
	public static int CACHE_MAX_SIZE = 10;
	private int cacheSize = CACHE_MAX_SIZE;
	
	/**
	 * -
	 * 
	 * @category 新引用管理集合
	 * */
	public HashMap<String, SabonaCacheEntry> NEW_CACHE = new HashMap<String, SabonaCacheEntry>();

	/**
	 * -
	 * 
	 * @category 旧引用管理集合
	 * */
	public HashMap<String, SabonaCacheEntry> OLD_CACHE = new HashMap<String, SabonaCacheEntry>();

	/**
	 * @category 锁对象
	 * */
	private final static Object LOCK_OBJ = new Object();

	/**
	 * @category 清除缓存中的所有对象
	 * */
	public void cleanUpCache() {
		synchronized (LOCK_OBJ) {
			NEW_CACHE.values().clear();
			NEW_CACHE.clear();
			OLD_CACHE.values().clear();
			OLD_CACHE.clear();
			System.gc();
			System.runFinalization();
		}
	}

	/**
	 * @category 清理多出的缓存
	 * */
	public void cleanOutCache() {
		// 缓冲区是否超出大小
		if (cacheSize < NEW_CACHE.size()) {
			// 清理
			synchronized (LOCK_OBJ) {
				OLD_CACHE.values().clear();
				OLD_CACHE.clear();
				System.gc();
				System.runFinalization();
				OLD_CACHE = NEW_CACHE;
				NEW_CACHE = new HashMap<String, SabonaCacheEntry>();
			}

		}
	}

	/**
	 * @category 通过主键寻找缓存
	 * @return 缓存,找不到返回null
	 */
	private SabonaCacheEntry getCache(String id) {
		SabonaCacheEntry cache = NEW_CACHE.get(id);
		if (null == cache) {
			cache = OLD_CACHE.get(id);
		}
		return cache;
	}

	/**
	 * @category 插入缓存 缓存对象
	 * */
	private void putCache(SabonaCacheEntry cache) {
		synchronized (LOCK_OBJ) {
			NEW_CACHE.put(cache.id, cache);
		}
	}

	/**
	 * @category 添加新的缓存
	 * @param model
	 *            要放入缓存中的对象
	 * */
	public void AddCache(SabonaCacheEntry model) {
		// 先判断内存是否已经达到上限要求
		cleanOutCache();
		putCache(model);
	}

	/**
	 * @category 获取缓存
	 * @param id
	 *            缓存的主键
	 * @return 缓存,如果找不到返回null,返回null的时候请调用AddCache放入新的缓存
	 * */
	public SabonaCacheEntry getCacheById(String id) {
		return getCache(id);
	}

	/**
	 * @category 移除指定id的缓存
	 * @param id
	 *            缓存的主键
	 * */
	public void removeCache(String id) {
		synchronized (LOCK_OBJ) {
			if (NEW_CACHE.containsKey(id)) {
				NEW_CACHE.remove(id);
			} else if (OLD_CACHE.containsKey(id)) {
				OLD_CACHE.remove(id);
			}
		}
	}
}
